# adb util functions
function adb_ready()
{
    if [ "$ADB_READY" = "1" ];then
        #echo "adb already ready ok!"
        return
    fi
    adb root
    adb wait-for-device remount
    ADB_READY=1
}

function adb_is_file()
{
    local RESULT=$(adb shell "[[ -f $1 ]] && echo yes || echo no")
    echo $RESULT
}

function adb_is_dir()
{
    local RESULT=$(adb shell "[[ -d $1 ]] && echo yes || echo no")
    echo $RESULT
}

function adb_mkdir()
{
    (set -x; adb shell mkdir -p $@)
}

function adb_run()
{
    (set -x; adb shell "$*")
}

function adb_pull()
{
    local A_SRC FILES_COUNT FILES SRC_FILENAME
    A_SRC=$1
    SRC_FILENAME=${A_SRC##*/}

    if [[ $SRC_FILENAME =~ '*' ]];then
        FILES_COUNT=$(adb shell "ls $A_SRC 2> /dev/null | wc -l")
        if [ $FILES_COUNT -eq 0 ];then
            echo "not found files match $A_SRC in devices!"
            return 0
        fi

        FILES=$(adb shell "ls $A_SRC 2> /dev/null")
        for data_file in $FILES
        do
            adb pull $data_file $2
        done
        #return $FILES_COUNT
    else
        adb pull $@
        #return 1
    fi
}

function adb_single_push()
{
    local SRC FILES_COUNT SRC_FILENAME  FILES
    local DST
    SRC=$1
    DST=$2
    SRC_FILENAME=${SRC##*/}
    if [[ $SRC_FILENAME =~ '*' ]];then
        FILES_COUNT=$(ls ${SRC} 2> /dev/null | wc -l)
        if [ $FILES_COUNT -eq 0 ];then
            echo "not found files match $SRC!"
            return
        fi

        FILES=$(ls ${SRC})
        for data_file in $FILES
        do
            adb_sync_push $data_file $DST
        done
        return
    fi

    if [ -d "$SRC" ];then
        adb_dir_push $@
        return
    fi

    if [ -f "$SRC" ];then
        adb_sync_push $@
        return
    fi
}

function adb_push()
{
    
    local DST    
    if [ $# -lt 2 ];then
        echo "adb_push need >=2 parameters, usage: adb_push file1 file2 dir1 <target_dir>"
        return    

    elif [ $# -eq 2 ];then
        adb_single_push $@
        return
    fi

    DST=${!#}
    for arg in "${@:1:$#-1}"; do
        adb_single_push $arg $DST
    done    
}

function adb_dir_push()
{
    local IN_SRC OUT_DST OUT_IS_DIR SRC_DIR DST_DIR last_char
    IN_SRC=$1
    OUT_DST=$2
    last_char=${OUT_DST: -1}

    if [ ! -d "$IN_SRC" ];then
        echo "adb_dir_push only support push directory, directory $IN_SRC not exists!"
        exit -1
    fi

    SRC_DIR=${IN_SRC##*/}
    OUT_IS_DIR=$(adb_is_dir $OUT_DST)

    # is directory
    if [ "$OUT_IS_DIR" = "yes" ];then
        if [ "$last_char" = "/" ];then
            DST_DIR=$OUT_DST"$SRC_DIR"
        else
            DST_DIR=$OUT_DST"/$SRC_DIR"
        fi
    else
        if [ "$last_char" = "/" ];then            
            DST_DIR=$OUT_DST"$SRC_DIR"
        else
            DST_DIR=$OUT_DST
        fi
    fi

    adb shell mkdir -p $DST_DIR
    FILES=$(ls $IN_SRC 2> /dev/null)

    for data_file in $FILES
    do
        if [ -d "$IN_SRC/$data_file" ];then
            adb_dir_push $IN_SRC/$data_file $DST_DIR/$data_file
            continue
        fi

        adb_sync_push $IN_SRC/$data_file $DST_DIR
    done
}

function adb_sync_push()
{
    local A_SRC B_DST SRC_FILENAME B_IS_DIR DST_FILE DEST_FILE_EXISTS REMOTE_MD5 LOCAL_MD5 last_char
    A_SRC=$1
    B_DST=$2
    last_char=${B_DST: -1}
   
    if [ ! -f "$A_SRC" ];then
        echo "adb_sync_push only support push single file, $A_SRC"
        exit -1
    fi

    SRC_FILENAME=${A_SRC##*/}
    B_IS_DIR=$(adb_is_dir $B_DST)

    # is directory
    if [ "$B_IS_DIR" = "yes" ];then
        if [ "$last_char" = "/" ];then
            DST_FILE=$B_DST"$SRC_FILENAME"
        else
            DST_FILE=$B_DST"/$SRC_FILENAME"
        fi
    else
        if [ "$last_char" = "/" ];then
            adb shell mkdir -p $B_DST
            DST_FILE=$B_DST"$SRC_FILENAME"
        else
            DST_FILE=$B_DST
        fi
    fi

    #echo "Src Path: $A_SRC, Dst Path: $DST_FILE"
    DEST_FILE_EXISTS=$(adb_is_file $DST_FILE)

    # not exists
    if [ "$DEST_FILE_EXISTS" = "no" ];then
        (set -x; adb push $A_SRC $DST_FILE)
        return $?
    fi

    REMOTE_MD5=$(adb shell "md5sum $DST_FILE | cut -d ' ' -f1")
    LOCAL_MD5=$(md5sum $A_SRC | cut -d ' ' -f1)

    #echo "remote md5: $REMOTE_MD5"
    #echo "local md5: $LOCAL_MD5"
    if [ "$REMOTE_MD5" != "$LOCAL_MD5" ];then
        echo "-----"
        (set -x; adb push $A_SRC $DST_FILE)
        echo "======"
    else
        echo "remote($DST_FILE) and local($A_SRC) is same, no need push it!"
    fi
    return 0
}

function adb_getprop()
{
    local ADB_PROP_VAL=$(adb shell getprop $1)
    echo $ADB_PROP_VAL
}

function adb_setprop()
{
    (set -x; adb shell setprop $1 $2)
}

function adb_device()
{
    local BOARD DEVICE VERSION

    adb_ready
    #BOARD=$(adb_getprop ro.product.board)
    #echo "target device prop[ro.product.board]: $BOARD"
    #DEVICE=$(adb_getprop ro.product.device)
    #echo "target device prop[ro.product.device]: $DEVICE"
    VERSION=$(adb_getprop ro.build.version.release)
    #echo "target device prop[ro.build.version.release]: $VERSION"
    ANDROID_VERSION="${VERSION//[$'\t\r\n ']}"

    if [ $ANDROID_VERSION -ge 10 ];then
        #echo "target device >= Android Q"
        ANDROID_GE_Q=1
        #return 1
    else
        ANDROID_GE_Q=0
        #return 0
    fi
}
